![]() |
Java Database Programming with JDBC
by Pratik Patel Coriolis, The Coriolis Group ISBN: 1576100561 Pub Date: 10/01/96 |
Previous | Table of Contents | Next |
I have found it quite useful for both the application and the driver to be able to test for the presence of a tracing PrintStream. The JDBC API provides us with a method to determine if tracing is enabled, as shown here:
//------------------------------------------------------------------------ // traceOn // Returns true if tracing (logging) is currently enabled //------------------------------------------------------------------------ public static boolean traceOn() { // If the DriverManager log stream is not null, tracing // must be currently enabled. return (DriverManager.getLogStream() != null); }
From an application, you can use this method to check if tracing has been previously enabled before blindly setting it:
// Before setting tracing on, check to make sure that tracing is not // already turned on. If it is, notify the application. if (traceOn()) { // Issue a warning that tracing is already enabled . . . }
From the driver, I use this method to check for tracing before attempting to send information to the PrintStream. In the example where we traced the message text of Trace=The quick brown fox jumped over the lazy dog, a lot had to happen before the message was sent to the DriverManager.println method. All of the given String objects had to be concatenated, and a new String had to be constructed. Thats a lot of overhead to go through before even making the println call, especially if tracing is not enabled (which will probably be the majority of the time). So, for performance reasons, I prefer to ensure that tracing has been enabled before assembling my trace message:
// Send some information to the JDBC trace OutputStream String a = "The quick brown fox "; String b = "jumped over the "; String c = "lazy dog"; // Make sure tracing has been enabled if (traceOn()) { DriverManager.println("Trace=" + a + b + c); }
At the heart of every JDBC driver is data. That is the whole purpose of the driver: providing data. Not only providing it, but providing it in a requested format. This is what data coercion is all aboutconverting data from one format to another. As Figure 10.1 shows, JDBC specifies the necessary conversions.
Figure 10.1 JDBC data conversion table.
In order to provide reliable data coercion, a data wrapper class should be used. This class contains a data value in some known format and provides methods to convert it to a specific type. As an example, I have included the CommonValue class from the SimpleText driver in Listing 10.13. This class has several overloaded constructors that accept different types of data values. The data value is stored within the class, along with the type of data (String, Integer, etc.). A series of methods are then provided to get the data in different formats. This class greatly reduces the burden of the JDBC driver developer, and can serve as a fundamental class for any number of drivers.
Listing 10.13 The CommonValue class.
package jdbc.SimpleText; import java.sql.*; public class CommonValue extends Object { //------------------------------------------------------------------------ // Constructors //------------------------------------------------------------------------ public CommonValue() { data = null; } public CommonValue(String s) { data = (Object) s; internalType = Types.VARCHAR; } public CommonValue(int i) { data = (Object) new Integer(i); internalType = Types.INTEGER; } public CommonValue(Integer i) { data = (Object) i; internalType = Types.INTEGER; } public CommonValue(byte b[]) { data = (Object) b; internalType = Types.VARBINARY; } //----------------------------------------------------------------------- // isNull // returns true if the value is null //------------------------------------------------------------------------ public boolean isNull() { return (data == null); } //------------------------------------------------------------------------ // getMethods //------------------------------------------------------------------------ // Attempt to convert the data into a String. All data types // should be able to be converted. public String getString() throws SQLException { String s; // A null value always returns null if (data == null) { return null; } switch(internalType) { case Types.VARCHAR: s = (String) data; break; case Types.INTEGER: s = ((Integer) data).toString(); break; case Types.VARBINARY: { // Convert a byte array into a String of hex digits byte b[] = (byte[]) data; int len = b.length; String digits = "0123456789ABCDEF"; char c[] = new char[len * 2]; for (int i = 0; i < len; i++) { c[i * 2] = digits.charAt((b[i] >> 4) & 0x0F); c[(i * 2) + 1] = digits.charAt(b[i] & 0x0F); } s = new String(c); } break; default: throw new SQLException("Unable to convert data type to String: " + internalType); } return s; } // Attempt to convert the data into an int public int getInt() throws SQLException { int i = 0; // A null value always returns zero if (data == null) { return 0; } switch(internalType) { case Types.VARCHAR: i = (Integer.valueOf((String) data)).intValue(); break; case Types.INTEGER: i = ((Integer) data).intValue(); break; default: throw new SQLException("Unable to convert data type to String: " + internalType); } return i; } // Attempt to convert the data into a byte array public byte[] getBytes() throws SQLException { byte b[] = null; // A null value always returns null if (data == null) { return null; } switch(internalType) { case Types.VARCHAR: { // Convert the String into a byte array. The String must // contain an even number of hex digits. String s = ((String) data).toUpperCase(); String digits = "0123456789ABCDEF"; int len = s.length(); int index; if ((len % 2) != 0) { throw new SQLException( "Data must have an even number of hex digits"); } b = new byte[len / 2]; for (int i = 0; i < (len / 2); i++) { index = digits.indexOf(s.charAt(i * 2)); if (index < 0) { throw new SQLException("Invalid hex digit"); } b[i] = (byte) (index << 4); index = digits.indexOf(s.charAt((i * 2) + 1)); if (index < 0) { throw new SQLException("Invalid hex digit"); } b[i] += (byte) index; } } break; case Types.VARBINARY: b = (byte[]) data; break; default: throw new SQLException("Unable to convert data type to byte[]: " + internalType); } return b; } protected Object data; protected int internalType; }
Previous | Table of Contents | Next |